package com.zxmr.utility.action;

import com.alibaba.fastjson.JSON;
import com.zxmr.action.Request;
import com.zxmr.action.Response;
import com.zxmr.action.ResponsePayload;
import com.zxmr.action.ResultCode;
import com.zxmr.domain.account.AccountType;
import com.zxmr.domain.account.User;
import com.zxmr.domain.file.File;
import com.zxmr.domain.file.Folder;
import com.zxmr.domain.file.ResourceAction;
import com.zxmr.domain.file.ResourceLevel;
import com.zxmr.domain.service.ResourceService;
import com.zxmr.navigate.ExecuteException;
import com.zxmr.navigate.Executor;
import com.zxmr.util.ResourceManager;
import com.zxmr.util.Utils;
import com.zxmr.utility.service.UserActionTraceService;

public class FileAction extends Executor{

	enum method{
		update,
		move,
		delete,
	}
	@Override
	public void execute(Request request, Response response) {
		
		try
		{
			method m = Enum.valueOf(method.class, this.getElement().getMethod());
			switch(m)
			{
			case update:
				update(request,response);
				break;
			case move:
				break;
			case delete:
				delete(request,response);
				break;
			}

		}catch(Exception e)
		{
			ResponsePayload payload = new ResponsePayload();
			if(e instanceof ExecuteException)
			{
				payload.setValue(e.getMessage());
			}else
			{
				e.printStackTrace();
				payload.setValue("internal error");
			}
			response.setPayload(payload);
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
	}

	private void delete(Request request,Response response)throws ExecuteException
	{
		long id = 0;
		try
		{
			id = Long.parseLong(request.getRequestParameters().get("id"));
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		}
		ResourceService service = new ResourceService();
		File file = service.queryFile(id, request.getAccount().getCompany());
		if(file == null)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.folder.empty"));
		
		if(request.getAccount().getAccountType() != AccountType.Supervisor
				&& !request.getAccount().getName().equals(file.getOwner()))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.noauth"));
		
		if(!service.deleteFile(file))
			this.internalErrorResponse(response);
		else
		{
			UserActionTraceService userTraceService = new UserActionTraceService();
			String action  = ResourceManager.getInstance().getMessage("com.zxmr.utility.deleteFile", String.valueOf(file.getId()),file.getName());
			userTraceService.addActionTrace(request.getAccount(), action);
		}
		
	}
	private void update(Request request,Response response)throws ExecuteException
	{
		File file = parseInput(request);
		if(file.getId() <= 0)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		
		ResourceService service = new ResourceService();
		
		File orign = service.queryFile(file.getId(), request.getAccount().getCompany());
		
		orign.setDescription(file.getDescription());
		orign.setLastUpdateTime(Utils.getCurrentTime());
		orign.setLastUpdateUser(request.getAccount().getName());
		orign.setName(file.getName());
		orign.setParent(file.getParent());
		orign.setLevel(file.getLevel());
		
		validateUpdateAuth(orign,request.getAccount());
		
		if(!service.updateFile(orign))
		{
			this.internalErrorResponse(response);
		}else
		{
			UserActionTraceService userTraceService = new UserActionTraceService();
			String action  = ResourceManager.getInstance().getMessage("com.zxmr.utility.updateFile", String.valueOf(file.getId()),file.getName());
			userTraceService.addActionTrace(request.getAccount(), action);
		}
	}
	private void validateUpdateAuth(File file,User user)throws ExecuteException
	{

		if(file == null)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.folder.empty"));
		
		if(!user.getName().equals(file.getOwner()) && user.getAccountType() != AccountType.Supervisor)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.file.noauth.update"));
		
		long parent = file.getParent();
		
		if(parent != 0 )
		{
			ResourceService service = new ResourceService();
			Folder par = service.queryFolder(parent, file.getCompany());
			if(par == null)
				throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.folder.empty"));
			// if user is the owner of the folder
			if(!user.getName().equals(par.getOwner()) && user.getAccountType() != AccountType.Supervisor)
			{
				if(par.getLevel() == ResourceLevel.Private)
					throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.folder.noauth.addfile"));
				else if(par.getLevel() == ResourceLevel.Protected)
				{
					if(!service.isUserAuthorizedForAction(par.getId(), user, ResourceAction.addFile))
						throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.folder.noauth.addfile"));
				}
			}
				
		}
	}
	private File parseInput(Request request)throws ExecuteException
	{
		try
		{
			return JSON.parseObject(request.getRequestParameters().get("parameters"), File.class);
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		}
	}
}
